package com.example.shrio.conf;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import com.example.util.RedisKeys;

/**
 * 将用户session存入redis
 * 
 * @author wangkai
 *
 * @date: 2019年5月30日 下午1:15:20
 */
public class RedisShiroSessionDAO extends EnterpriseCacheSessionDAO {

	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;

	// 创建session
	@Override
	protected Serializable doCreate(Session session) {
		Serializable sessionId = super.doCreate(session);
		return sessionId;
	}

	// 获取session
	@Override
	protected Session doReadSession(Serializable sessionId) {
		Session session = super.doReadSession(sessionId);
		if (session == null) {
			final String key = RedisKeys.getShiroSessionKey(sessionId.toString());
			session = getShiroSession(key);
		}
		return session;
	}

	// 更新session
	@Override
	protected void doUpdate(Session session) {
		if (session instanceof ShiroSession) {
			ShiroSession ss = (ShiroSession) session;
			if (ss.isChanged()) {// 未登录
				final String key = RedisKeys.getShiroSessionKey(ss.getId().toString());
				setShiroSession(key, ss);
			}
		}
		super.doUpdate(session);
	}

	// 删除session
	@Override
	protected void doDelete(Session session) {
		super.doDelete(session);
		final String key = RedisKeys.getShiroSessionKey(session.getId().toString());
		redisTemplate.delete(key);
	}

	/**
	 * 
	 * @param key
	 * @param outTime
	 * @param unit
	 */
	public void expireRedisKey(String key, Integer outTime, TimeUnit unit) {
		redisTemplate.expire(key, outTime, unit);
	}

	private Session getShiroSession(String key) {
		Object obj = redisTemplate.opsForValue().get(key);
		if (obj != null) {
			return (ShiroSession) obj;
		}
		return null;
	}

	private void setShiroSession(String key, ShiroSession session) {
		redisTemplate.opsForValue().set(key, session);
		// 60分钟过期
		expireRedisKey(key, 30, TimeUnit.MINUTES);
	}

}
